Skip to content

policy: Phase 0 non-destructive policy handling + current branch updates#11

Merged
CJFWeatherhead merged 7 commits into
mainfrom
test/expand-mock-api-fixtures
Jul 3, 2026
Merged

policy: Phase 0 non-destructive policy handling + current branch updates#11
CJFWeatherhead merged 7 commits into
mainfrom
test/expand-mock-api-fixtures

Conversation

@CJFWeatherhead

Copy link
Copy Markdown
Member

Summary

This PR includes all files currently on branch test/expand-mock-api-fixtures and targets privacyint/headscale-admin:main.

It delivers the Phase 0 safety patch from docs/headscale-0.29.x-agentic-workplan.md while also carrying the branch's in-flight updates (UI/test/mock/openapi/tooling assets) as requested.

Phase 0 changes (implemented)

1) Lossless policy document abstraction

  • Added src/lib/common/policy-document.ts with:
    • parsePolicyDocument(...)
    • mergeLegacyPolicyDocument(...)
    • serialisePolicyDocument(...)
  • Preserves unknown/modern policy fields while exposing legacy ACL sections for current UI/editor flows.

2) Non-destructive save integration

  • Updated src/lib/common/acl.svelte.ts:
    • ACLBuilder.fromPolicy(...) now parses through policy document abstraction.
    • ACLBuilder.JSON(...) now merges edited legacy sections into original raw policy before save.
    • Added compatibility helpers:
      • hasUnsupportedPolicyFields()
      • getUnsupportedPolicyFields()

3) Explicit compatibility warning UX

  • Added warning banner in:
    • src/routes/acls/+page.svelte
    • src/routes/acls/Config.svelte
  • Purpose: make users aware that advanced fields exist outside the legacy ACL editor model, while preserving those fields on save.

4) Unit tests for lossless round-trip

  • Added src/lib/common/policy-document.test.ts covering:
    • parse → serialise round-trip for mixed ACL + modern fields (grants, nodeAttrs, randomizeClientPort),
    • merge semantics (legacy edits applied without dropping unknown sections).

Additional branch updates included (as requested)

This PR also includes the branch’s existing non-Phase-0 files:

  • Tooling and linting config under .trunk/
  • Docs/workplan file updates
  • E2E and mock API updates
  • OpenAPI update
  • Node/user card and route UI updates
  • Additional UI components (tag badges/icons)
  • Asset update (logo.svg)

Files changed

  • .trunk/.gitignore
  • .trunk/configs/.hadolint.yaml
  • .trunk/configs/.markdownlint.yaml
  • .trunk/configs/.yamllint.yaml
  • .trunk/trunk.yaml
  • docs/headscale-0.29.x-agentic-workplan.md
  • e2e/docker.spec.ts
  • e2e/mock-api.mjs
  • e2e/navigation.spec.ts
  • logo.svg
  • openapiv2.json
  • src/lib/cards/node/NodeListCard.svelte
  • src/lib/cards/node/NodeOwner.svelte
  • src/lib/cards/node/NodeTileCard.svelte
  • src/lib/cards/user/UserListNodes.svelte
  • src/lib/cards/user/UserTileCard.svelte
  • src/lib/common/acl.svelte.ts
  • src/lib/common/policy-document.test.ts
  • src/lib/common/policy-document.ts
  • src/lib/parts/NodeTagsIcon.svelte
  • src/lib/parts/TagBadge.svelte
  • src/routes/acls/+page.svelte
  • src/routes/acls/Config.svelte
  • src/routes/users/+page.svelte

Test evidence

Executed in Node 20 Alpine container:

  1. vitest src/lib/common/policy-document.test.ts

    • ✅ Passed (1 file, 2 tests)
  2. vitest src/index.test.ts src/lib/common/policy-document.test.ts

    • ✅ Passed (2 files, 48 tests total)

Known limitations

  • Phase 0 warning detection is advisory and currently focused on:
    • unsupported top-level fields,
    • unsupported keys in acls[] / ssh[] entries.
  • This PR intentionally includes broader branch deltas beyond strict Phase 0 because the request was to bring in all files.

Follow-up recommendations

  1. Add an E2E regression for: load mixed policy → edit legacy ACL section → save → verify advanced fields unchanged.
  2. Phase 1: migrate towards first-class modern policy model/types and retire legacy assumptions.
  3. Consider splitting future work into smaller phase-only PRs to reduce review surface.

Non-goals

  • No Headscale 0.30 API migration.
  • No broad redesign of ACL UX beyond Phase 0 safety warning and non-destructive write behaviour.

CJFWeatherhead and others added 7 commits May 1, 2026 15:33
Grows the fixture dataset from ~5 nodes / 2 users to:
- 25 users (local, OIDC/Google, OIDC/Azure, OIDC/GitHub, service accounts,
  long names, unicode display names, legacy epoch creation dates)
- 91 nodes distributed unevenly across users + tagged-devices:
  - Group A: personal workstations/laptops (mixed online/offline, expiry states)
  - Group B: 6 exit nodes (dual-stack approved, IPv4-only, IPv6-only,
    unapproved, expiring soon, offline)
  - Group C: 8 route-provider nodes (RFC1918 /24, /16, /8, overlapping
    subnets, IPv6 ULA, dual-stack, pending approval, many-routes overflow)
  - Group D: 22 tagged nodes under tagged-devices (single/multi tag,
    k8s cluster, IoT, cameras, printers, orphaned nodes, never-seen node,
    tagged exit node, tagged router)
  - Group E: edge cases (null lastSeen, IPv4-only, IPv6-only addresses,
    REGISTER_METHOD_UNSPECIFIED, multi-IP node, overflow name/givenName)
- 11 pre-auth keys (reusable, ephemeral, used, expired, tagged, multi-tag,
  expiring-soon, service-account)
- 3 API keys (healthy, expiring-soon, expired)
- Richer ACL policy (groups, hosts, tagOwners, SSH rules)
- userNodeMap built dynamically from fixture data (includes originalUser
  attribution for tagged-device nodes)

Smoke-tested via Docker: 25 users, 91 nodes, 11 preAuthKeys returned.
@CJFWeatherhead CJFWeatherhead merged commit 193e38f into main Jul 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant